package ldh.im.fxgui.component.message;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import javafx.scene.Node;
import javafx.scene.control.ListView;
import javafx.scene.layout.StackPane;
import ldh.im.fxbase.cell.ObjectListCell;
import ldh.im.fxbase.data.pojo.ImMessage;
import ldh.im.fxgui.handle.IMessageEditorHandler;
import ldh.im.fxgui.component.message.bo.WrapImMessage;

import java.util.List;
import java.util.stream.Collectors;

public class MessageListView extends BaseMessageListViewHandler {

    private ListView<WrapImMessage> messageList;
    private ObservableList<WrapImMessage> items = FXCollections.observableArrayList();
    private FilteredList<WrapImMessage> filteredData = new FilteredList<>(items, s -> true);
    private SortedList<WrapImMessage> sortedList = new SortedList<WrapImMessage>(filteredData, this::messageComparator);

    public MessageListView(IMessageEditorHandler messageEditorService, StackPane dialogRoot) {
        super(messageEditorService, dialogRoot);
    }

    @Override
    public Node createMessagePaneNode() {
        messageList = new ListView<>();
        messageList.setItems(sortedList);
        messageList.setCellFactory(new ObjectListCell<>(message -> createMessagePane(message)));
//        messageList.setCellCallback(message -> createMessagePane((Message)message));
        return messageList;
    }

    @Override
    public boolean addMessage(ImMessage message) {
        if (!canShowMessage(message)) {
            return false;
        }
        WrapImMessage wrapImMessage = WrapImMessage.wrap(message);
        items.add(wrapImMessage);
        removeMore(); // 移除过多数据
        messageList.getSelectionModel().select(wrapImMessage);
        messageList.scrollTo(wrapImMessage);
        return true;
    }

    @Override
    public void addMessage(int index, ImMessage message) {
        if (!canShowMessage(message)) {
            return;
        }
        WrapImMessage wrapImMessage = WrapImMessage.wrap(message);
        items.add(index, wrapImMessage);
        removeMore(); // 移除过多数据
        messageList.scrollTo(wrapImMessage);
//        messageList.getSelectionModel().select(message);
    }

    @Override
    public void addMessages(List<ImMessage> messages) {
        if (!canShowMessage(messages.get(0))) {
            return;
        }
        List<WrapImMessage> wrapImMessages = messages.stream().map(m->WrapImMessage.wrap(m)).collect(Collectors.toList());
        items.addAll(wrapImMessages);
        removeMore(); // 移除过多数据
        messageList.scrollTo(messageList.getItems().size()-1);
//        messageList.getSelectionModel().select(messageList.getItems().size()-1);
    }

    @Override
    public ImMessage getFirstMessage() {
        if (sortedList.size() > 0) {
            return sortedList.get(0).getImMessage();
        }
        return null;
    }

    @Override
    public ImMessage getLastedMessage() {
        if (sortedList.size() > 0) {
            return sortedList.get(sortedList.size() - 1).getImMessage();
        }
        return null;
    }

    @Override
    public void addFrontMessages(List<ImMessage> messages) {
        if (!canShowMessage(messages.get(0))) {
            return;
        }
        WrapImMessage selectedWrapImMessage = messageList.getSelectionModel().getSelectedItem();
        List<WrapImMessage> wrapImMessages = messages.stream().map(m->WrapImMessage.wrap(m)).collect(Collectors.toList());
        items.addAll(0, wrapImMessages);
        removeLastMore(); // 移除过多数据
        messageList.getSelectionModel().select(selectedWrapImMessage);
        messageList.scrollTo(sortedList.indexOf(selectedWrapImMessage));
    }

    @Override
    public void addLastedMessages(List<ImMessage> messages) {
        if (messages.size() < 1) return;
        if (!canShowMessage(messages.get(0))) {
            return;
        }
        WrapImMessage selectedWrapImMessage = messageList.getSelectionModel().getSelectedItem();
        List<WrapImMessage> wrapImMessages = messages.stream().map(m->WrapImMessage.wrap(m)).collect(Collectors.toList());
        items.addAll(wrapImMessages);
        removeMore(); // 移除过多数据

        messageList.getSelectionModel().select(selectedWrapImMessage);
        messageList.scrollTo(sortedList.indexOf(selectedWrapImMessage));
    }

    @Override
    public ObservableList<WrapImMessage> getItems() {
        return items;
    }
}
